package com.cancer.biz.common;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cancer.biz.base.service.SysParamService;
import com.cancer.common.web.ApplicationContextUtils;

import io.vertx.core.json.JsonObject;
import net.sf.json.JSONObject;

/**
 * 系统运行时所需的配置文件，在系统启动时初始化方法必须被调用。
 *
 * @Company GeekPlus
 * @Project beetle
 * @since 1.0.0
 * @Author ck
 * @Date 2015年12月8日 上午10:28:59
 * @Description
 */
public final class SysConfigUtils {
	private static Logger logger = LoggerFactory.getLogger(SysConfigUtils.class);
	// 系统配置文件所在位置
	private static Properties sysconfigPropterties = null;

	private static Timer reloadTimer = null;
	private static SysParamService sysParamService = null;

	/*
	 * 刷新数据库配置到内存 sysconfigPropterties
	 * 每过10秒从数据库读取
	 *
	 * @author yuzc 2017年5月17日
	 * @param
	 * @return
	 * */
	public static void timerLoad() {
		reloadTimer = new Timer();

		//启用新的调度
		reloadTimer.scheduleAtFixedRate(new TimerTask() {
			public void run() {
				//logger.info("timerLoad runing...");

				try {
					initSysConfigUtils();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}, 10 * 1000, 10 * 1000);
	}

	/***
	 * 描述：初始化SysConfigUtils,只在系统启动时调用
	 *
	 * @throws IOException 文件无法找到异常
	 */
	public static void init() throws IOException {
		try {
			initSysConfigUtils();
		} catch (IOException e) {
			logger.error(
					"initialize sysconfigUtils failed ,because some file not find or config file's contents have errors,please check!");
			throw e;
		}

//		if (reloadTimer == null) {
//			timerLoad();
//		}
	}

	@SuppressWarnings("rawtypes")
	private static void initSysConfigUtils() throws IOException {
		if (sysParamService == null) {
			sysParamService = ApplicationContextUtils.getBean(SysParamService.class);
		}

		// 1.加载系统配置文件
		if (sysParamService != null) {
			sysconfigPropterties = sysParamService.queryParamsAsProperties(null, null, true);
		}
	}

	/***
	 * 描述：获取配置文件中所有的键
	 *
	 * @return 返回键的集合
	 */
	@SuppressWarnings("rawtypes")
	public static List<String> getKeys() {

		List<String> ls = new ArrayList<>();
		Enumeration en = sysconfigPropterties.propertyNames();
		while (en.hasMoreElements())
			ls.add((String) en.nextElement());
		return ls;
	}

	/**
	 * 描述：获取配置问价中所有的值
	 *
	 * @return 返回值列表
	 */
	@SuppressWarnings("rawtypes")
	public static List getValues() {
		return new ArrayList<>(sysconfigPropterties.values());
	}

	/***
	 * 描述：根据键获取对应的值
	 *
	 * @param key 键
	 * @return 返回值
	 */
	public static String getValue(String key) {
		return sysconfigPropterties.getProperty(key);
	}

	/**
	 * 描述：根据键获取对应的值，如果不存在返回defaultValue
	 *
	 * @param key
	 * @param defaultValue
	 * @return
	 */
	public static String getValue(String key, String defaultValue) {
		String value = sysconfigPropterties.getProperty(key);
		if (value == null) {
			return defaultValue;
		} else {
			return value;
		}
	}

	/***
	 * 描述：根据键获取对应的值
	 *
	 * @param key 键
	 * @return 返回值
	 */
	public static int getIntegerValue(String key) {
		try {
			String val = sysconfigPropterties.getProperty(key);
			return Integer.parseInt(val);
		} catch (Exception e) {
			return 0;
		}
	}

	/***
	 * 描述：根据键获取对应的值
	 *
	 * @param key 键
	 * @return 返回值
	 */
	public static long getLongValue(String key) {
		try {
			String val = sysconfigPropterties.getProperty(key);
			return Long.parseLong(val);
		} catch (Exception e) {
			return 0L;
		}
	}

	/***
	 * 描述：根据键获取对应的值
	 *
	 * @param key 键
	 * @return 返回值
	 */
	public static double getDoubleValue(String key) {
		try {
			String val = sysconfigPropterties.getProperty(key);
			return Double.parseDouble(val);
		} catch (Exception e) {
			return 0;
		}
	}

	/***
	 * 描述：根据键获取对应的值
	 *
	 * @param key 键
	 * @return 返回值
	 */
	public static boolean getBooleanValue(String key) {
		try {
			String val = sysconfigPropterties.getProperty(key);
			return "true".equalsIgnoreCase(val);
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 描述：获取配置问价中所有的k-v
	 *
	 * @return 返回k-v的map集合
	 */
	@SuppressWarnings("rawtypes")
	public static Map<String, String> getKV() {
		Map<String, String> map = new HashMap<>();
		Enumeration en = sysconfigPropterties.propertyNames();
		while (en.hasMoreElements()) {
			String key = (String) en.nextElement();
			String value = sysconfigPropterties.getProperty(key);
			map.put(key, value);
		}
		return map;
	}

	/***
	 * 描述：生成小写的UUID
	 *
	 * @return 返回小写的UUID
	 */
	public static String getLowCaseUUID() {
		return UUID.randomUUID().toString().toLowerCase();
	}

	/**
	 * 描述：获取大写的UUID
	 *
	 * @return 返回大写的UUID
	 */
	public static String getUppperCaseUUID() {
		return UUID.randomUUID().toString().toUpperCase();
	}

	/***
	 * 运行是修改内存中的初始值
	 *
	 * @param key 键
	 * @param value 值
	 */
	public static void setValue(String key, String value) {
		sysconfigPropterties.setProperty(key, value);
	}
	
	/**
     * 将xml转化为Map集合
     * 
     * @param request
     * @return
     */
    public static JsonObject xmlToJsonObject(HttpServletRequest request) {
    	JsonObject map = new JsonObject();
        SAXReader reader = new SAXReader();
        InputStream ins = null;
        try {
            ins = request.getInputStream();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        Document doc = null;
        try {
            doc = reader.read(ins);
        } catch (DocumentException e1) {
            e1.printStackTrace();
        }
        Element root = doc.getRootElement();
        @SuppressWarnings("unchecked")
        List<Element> list = root.elements();
        for (Element e : list) {
            map.put(e.getName(), e.getText());
        }
        try {
            ins.close();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        return map;
    }
}
